package com.bz.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.bz.common.Codeenum;
import com.bz.common.PageInfo;
import com.bz.common.PageUtil;
import com.bz.common.RedisServiceUtil;
import com.bz.common.ResponseDto;
import com.bz.common.UserConfig;
import com.bz.entity.UserEntity;
import com.bz.model.MenuDto;
import com.bz.model.MenuTree;
import com.bz.service.IRoleService;
import com.bz.service.IUserService;

@RestController
@RequestMapping(value = "/admin/user")
public class UserController {

    @Autowired
    private IUserService     userService;

    @Autowired
    private IRoleService     roleService;

    @Autowired
    private RedisServiceUtil redisServiceUtil;

    @RequestMapping(value = "/list")
    public PageInfo list(@RequestParam(required = false) String searchText,
                         @RequestParam(required = false) String roleId,
                         @RequestParam(required = false) Long pageNo) {

        PageInfo page = PageUtil.getPageInfo(pageNo, PageUtil.pageSize);
        return userService.getUser(page, searchText, roleId);
    }

    @RequestMapping(value = "/info")
    public ResponseDto<UserEntity> info(@RequestParam(required = true) Long id) {
        return new ResponseDto<>(userService.info(id));
    }

    @RequestMapping(value = "/add")
    public ResponseDto<String> add(@RequestBody @Valid UserEntity data) {

        // 检查用户名是否重复
        Map<String, Object> parMap = new HashMap<>();
        parMap.put("user_name", data.getUsername());

        List<UserEntity> uList = userService.getUser(parMap);
        if (!CollectionUtils.isEmpty(uList)) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "用户名已经存在！");
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        data.setPassword(encoder.encode(data.getPassword()));

        UserEntity lu = UserConfig.getLoginUser();
        data.setCreateBy(lu.getUsername());
        data.setUpdateBy(lu.getUsername());
        data.setCreateDate(new Date());

        userService.insert(data, data.getRoles());
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "添加成功");

    }

    @RequestMapping(value = "/update")
    public ResponseDto<String> update(@RequestBody @Valid UserEntity data) {

        if (data.getId() <= 0) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "该用户不支持修改");
        }

        // 校验是否存在
        UserEntity userDto = userService.info(data.getId());
        if (null == userDto) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "数据不存在");
        }
        // 判断用户名是否需要校验
        if (!StringUtils.equals(userDto.getUsername(), data.getUsername())) {
            Map<String, Object> cparMap = new HashMap<>();
            cparMap.put("user_name", data.getUsername());
            List<UserEntity> cList = userService.getUser(cparMap);
            if (!CollectionUtils.isEmpty(cList)) {
                return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "用户名已经存在!");
            }
        }

        data.setId(userDto.getId());
        UserEntity lu = UserConfig.getLoginUser();
        data.setUpdateBy(lu.getUsername());

        userService.update(data, data.getRoles());
        redisServiceUtil.del(UserConfig.getUserKey(userDto.getUsername()));
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "修改成功");
    }

    @RequestMapping(value = "/set-password")
    public ResponseDto<String> updatePassword(@RequestParam(required = true) Long id,
                                              @RequestParam(required = true) String password) {

        if (id <= 0) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "该用户不支持修改");
        }

        Map<String, Object> parMap = new HashMap<>();
        parMap.put("id", id);

        // 校验是否存在
        List<UserEntity> dList = userService.getUser(parMap);
        if (CollectionUtils.isEmpty(dList)) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "数据不存在");
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        parMap.put("password", encoder.encode(password));

        UserEntity lu = UserConfig.getLoginUser();
        parMap.put("updateBy", lu.getUsername());

        userService.setPassword(id, encoder.encode(password));

        redisServiceUtil.del(UserConfig.getUserKey(dList.get(0).getUsername()));
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "修改成功");
    }

    @RequestMapping(value = "/delete")
    public ResponseDto<String> delete(@RequestParam(required = true) Long id) {

        if (id <= 0) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "该用户不支持修改");
        }

        Map<String, Object> parMap = new HashMap<>();
        parMap.put("id", id);

        // 校验是否存在
        List<UserEntity> dList = userService.getUser(parMap);
        if (CollectionUtils.isEmpty(dList)) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "数据不存在");
        }

        userService.delete(id);
        redisServiceUtil.del(UserConfig.getUserKey(dList.get(0).getUsername()));
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "删除成功");
    }

    @RequestMapping(value = "/menu")
    public List<MenuTree> menuTree() {
        UserEntity lu = UserConfig.getLoginUser();
        List<MenuDto> rlist = roleService.getMenuByUid(lu.getId());
        return roleService.convertTree(rlist);
    }

    @RequestMapping(value = "/stop")
    public ResponseDto<String> stop(@RequestParam(required = true) Long id) {

        if (id <= 0) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "该用户不支持修改");
        }

        Map<String, Object> parMap = new HashMap<>();
        parMap.put("id", id);

        // 校验是否存在
        List<UserEntity> dList = userService.getUser(parMap);
        if (CollectionUtils.isEmpty(dList)) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "数据不存在");
        }

        userService.updateStatus(id, "0");

        redisServiceUtil.del(UserConfig.getUserKey(dList.get(0).getUsername()));
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "停用成功");
    }

    @RequestMapping(value = "/start")
    public ResponseDto<String> start(@RequestParam(required = true) Long id) {

        if (id <= 0) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "该用户不支持修改");
        }

        Map<String, Object> parMap = new HashMap<>();
        parMap.put("id", id);

        // 校验是否存在
        List<UserEntity> dList = userService.getUser(parMap);
        if (CollectionUtils.isEmpty(dList)) {
            return new ResponseDto<>(Codeenum.ALL_ERROR.getCode(), "数据不存在");
        }

        userService.updateStatus(id, "1");
        redisServiceUtil.del(UserConfig.getUserKey(dList.get(0).getUsername()));
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "启用成功");
    }

    @RequestMapping(value = "/my-update")
    public ResponseDto<String> myUpate(@RequestBody @Valid UserEntity userDto) {
        userService.updateInfo(userDto);
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "修改成功");
    }

    @RequestMapping(value = "/my-password-update")
    public ResponseDto<String> myUpdatePassword(@RequestParam(required = true) String oldPassword,
                                                @RequestParam(required = true) String password) {
        userService.updatePassword(oldPassword, password);
        return new ResponseDto<>(Codeenum.SUCCESS.getCode(), "修改成功");
    }

    @RequestMapping(value = "/my-info")
    public ResponseDto<UserEntity> myInfo() {
        UserEntity authUserDto = UserConfig.getLoginUser();
        return new ResponseDto<>(userService.info(authUserDto.getId()));
    }
}
